#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>

#include "lex.hpp"
#include "syn.hpp"

using namespace std;

void print_log(ostream &out, vector<string> &log) {
	for (int cnt = 0; cnt < log.size(); ++cnt) {
		out << log[cnt] << endl;
	}
}

bool prefix_is_test(const char*str) {
	const char *test_prefix = "test";
	for (int cnt = 0; cnt < 4; ++cnt) {
		if (str[cnt] != test_prefix[cnt]) {
			return false;
		}
	}
	int len = strlen(str);
	for (int cnt = 4; cnt < len; ++cnt) {
		if (str[cnt] > '9' || str[cnt] < '0') {
			if (str[cnt] == '.') {
				return true;
			}
			return false;
		}
	}
	return true;
}

string patsub(const char *str, const char *sub) {
	char buff[50];
	if (prefix_is_test(str)) {
		strncpy(buff, str+4, 50);
	} else {
		strncpy(buff, str, 50);
	}
	char *tmp;
	tmp = strtok(buff, ".");
	string res(tmp);
	cout << res+sub << endl;
	return res+sub;
}

int main (int argc, char **argv) {
	assert(argc >= 2);
	int cnt;
	char *mode = argv[1];
	if (strcmp(mode, "-lr1") != 0 && strcmp(mode, "-ll1") != 0 && strcmp(mode, "-test") != 0) {
		mode = "-test";
		cnt = 1;
	} else {
		cnt = 2;
	}

	init_sym_tab();

	NFA nfa("tests/my_lex_rule.txt");
	// nfa.print_rules();
	// cout << endl << endl;

	DFA dfa(nfa);
	dfa.minimise();
	//dfa.print_rules();

	LR lr;
	LL ll;

	if (strcmp(mode, "-lr1") == 0 || strcmp(mode, "-test") == 0) {
		lr.read_rules("tests/grammar.txt");
		lr.expand();
		lr.build_predict();
	}

	if (strcmp(mode, "-ll1") == 0 || strcmp(mode, "-test") == 0) {
		ll.read_rules("tests/grammar.txt");
		ll.build_predict();
	}
	
	for (; cnt < argc; ++cnt) {
		char *input = argv[cnt];

		vector<Token> tokens;
		make_tokens(dfa, input, tokens);
		ofstream lex_out(patsub(input, "lex.txt"));
		//print_tokens(cout, tokens);
		print_tokens(lex_out, tokens);
		lex_out.close();

		if (strcmp(mode, "-lr1") == 0 || strcmp(mode, "-test") == 0) {
			auto lr_log = lr.analyse_tokens(tokens);
			ofstream out(patsub(input, "gra-lr.txt"));
			//print_log(cout, lr_log);
			print_log(out, lr_log);
			out.close();
		}

		if (strcmp(mode, "-ll1") == 0 || strcmp(mode, "-test") == 0) {
			auto ll_log = ll.analyse_tokens(tokens);
			ofstream out(patsub(input, "gra.txt"));
			//print_log(cout, ll_log);
			print_log(out, ll_log);
			out.close();
		}
	}

	return 0;
}
